require "LHHelpers"
require "LHAnimationsMgr"
--------------------------------------------------------------------------------
LHAnimationNode = {}

function imageFileWithFolder(imageFile)

	local imgFile = imageFile
	if(application ~= nil)then
		if(application.LevelHelperSettings ~= nil)then
			if(application.LevelHelperSettings.imagesSubfolder ~= nil)then
				imgFile = application.LevelHelperSettings.imagesSubfolder .. "/" .. imageFile;
			end
		end
	end

	return imgFile;
end
--------------------------------------------------------------------------------

function LHAnimationNode:initWithDictionary(properties, batchNodesSizes)
	if (nil == properties) then
		print("Invalid LHAnimationNode initialization!")
	end
	
	local object = {uniqueName = properties["UniqueName"],
					startAtLaunch = properties["StartAtLaunch"],
					image = properties["Image"],
					repetitions = properties["Repetitions"],
					speed = properties["Speed"],
					loop = properties["LoopForever"],	
					framesInfo = lhAnimatioNodeGetFramesTableFromDictionary(properties),
					nodeImagePath = nil,
					sheetData = nil,
					oldApiSheetData = nil,
					processedFrames = nil
					}
					

	setmetatable(object, { __index = LHAnimationNode })  -- Inheritance	
		
	object.image = imageFileWithFolder(object.image);
		
	local sprite = require("sprite")
			
	local spr_size = lh_rectFromString(object.framesInfo[1].rect).size
		
	object.sheetData = lhAnimationNodeOptionsForSheet(object, spr_size, object.image, batchNodesSizes);
	
	local spr_size = lh_rectFromString(object.framesInfo[1].rect).size
	object.oldApiSheetData = lhAnimationNodeOLD_APISheetDataForAnimNode(object, spr_size, 1.0);
	
	
	object.nodeImagePath = image;	
	object.processedFrames = lhAnimationNodeFramesArrayWithSize(#object.framesInfo);

	return object
end
--------------------------------------------------------------------------------
function LHAnimationNode:removeSelf()

	self.uniqueName = nil;
	self.startAtLaunch = nil;
	self.image = nil;
	self.repetitions = nil;
	self.speed = nil;
	self.loop = nil;
	self.framesInfo = nil;	
	self = nil;
end
--------------------------------------------------------------------------------
function imageFileSize(imageFile, batchNodesSizes)

	local batch = batchNodesSizes[imageFile];
	
	if(batch == nil)then
	
		local findSizeFromThisObject = display.newImage(imageFile, system.ResourceDirectory,  0, 0,  true);
		
		-- temporary fix until new LH binary
		batch = {width = findSizeFromThisObject.width, height = findSizeFromThisObject.height};
		batchNodesSizes[imageFile] = batch;
		findSizeFromThisObject:removeSelf();
	end

	return batch;
end
--------------------------------------------------------------------------------
function lhAnimationNodeOptionsForSheet(animNode, size, imageFile, batchNodesSizes)


	local batch = imageFileSize(imageFile, batchNodesSizes);	
	
	local options = { frames = {}, sheetContentWidth = batch.width, sheetContentHeight = batch.height };

	for j = 1, #animNode.framesInfo do
				
		local curFrame = animNode.framesInfo[j]
				
		local uvRect = lh_rectFromString(curFrame.rect)
		local frameName = curFrame.name
					
		options.frames[#options.frames +1] = 
		{
			name = frameName,
			x = uvRect.origin.x,
			y = uvRect.origin.y,
			width = uvRect.size.width,
			height= uvRect.size.height			
		}
	end	
	
	return options
end
--------------------------------------------------------------------------------
function lhAnimationNodeOLD_APISheetDataForAnimNode(animNode, size, rectMultiplier)

	local sheet = { frames = {} };

	for j = 1, #animNode.framesInfo do
				
		local curFrame = animNode.framesInfo[j]
				
		local uvRect = lh_rectFromString(curFrame.rect)
		local frameName = curFrame.name
					
		sheet.frames[#sheet.frames +1] = 
		{
			name = frameName,
			spriteColorRect = { x = uvRect.origin.x*rectMultiplier, 
								y = uvRect.origin.y*rectMultiplier, 
								width = uvRect.size.width*rectMultiplier, 
								height = uvRect.size.height*rectMultiplier }, 
			textureRect = { x = uvRect.origin.x*rectMultiplier, 
							y = uvRect.origin.y*rectMultiplier, 
							width = uvRect.size.width*rectMultiplier, 
							height = uvRect.size.height*rectMultiplier }, 
			spriteSourceSize = { width = size.width, 
								 height= size.height}, 
			spriteTrimmed = false,
			textureRotated = false
		}
	end		
	return sheet
end
--------------------------------------------------------------------------------
function lhAnimationNodeFramesArrayWithSize(size)
	
	local frmArray = {}
	for i=1, size do
		frmArray[#frmArray+1] = i
	end
	
	return frmArray
end
--------------------------------------------------------------------------------
function spriteFromAnimationsNodesAndSpriteInfo(animationNodes, 
												spriteInfo, 
												animationsSheet,
												batchNodesSizes)

--starting creating animations using the most ugly api i have ever seen.
--my head hurts when i need to change something here

	local settings = LHSettings:sharedInstance();
	
	local spr_name = spriteInfo["UniqueName"]
	local spr_animName = spriteInfo["AnimName"];
	local tag = spriteInfo["Tag"];
	
	
	local spr_uvRect = lh_rectFromString(spriteInfo["UV"])
	local spr_size = lh_sizeFromString(spriteInfo["Size"])
	
	local imageFile = spriteInfo["Image"];
	
	imageFile = imageFileWithFolder(imageFile);
	
	local batch = imageFileSize(imageFile, batchNodesSizes);
	
	
	local animationsListOnSprite = LHAnimationsMgr:sharedInstance():animationsOnSpriteWithName(spr_name);	
		
	if(animationsListOnSprite == nil)then
		animationsListOnSprite = LHAnimationsMgr:sharedInstance():animationsOnSpritesWithTag(tag);
	end
	
	if((spr_animName ~= nil and "" ~=  spr_animName and " " ~=  spr_animName and "No Animation" ~= spr_animName))
		and 
		(nil == animationsListOnSprite) then

		local sequenceData = {}
  			--  { name="walking", start=1, count=3 },
			--  { name="running", frames={ 3, 4, 5, 6, 7, 8 }, time=50, loopCount=4 },
			--  { name="jumping", start=9, count=13, time=300 }


		for i = 1, #animationNodes do
			local curNode = animationNodes[i];
	
			local loop = 0;
			if false == curNode.loop then
				loop = curNode.repetitions
			end

			local speed = curNode.speed;
			if(speed < 0.001)then
				speed = 0.001
			end
			speed = speed*(#curNode.processedFrames)*1000;

			if spr_animName == curNode.uniqueName then		
		

				--print("NODE IMG " .. curNode.image);
				local imageSheet = graphics.newImageSheet( curNode.image, curNode.sheetData )

				--local coronaSprite = display.newImage( imageSheet, 1)
		 											 
		 		animationsSheet[#animationsSheet +1] = imageSheet;
			
				sequenceData[#sequenceData+1] = { name = curNode.uniqueName,
												  frames = curNode.processedFrames,
												  time = speed,
												  loopCount = loop,
												  imageSheet = imageSheet}
								
							
				local sequenceDataTest = {
						    name=curNode.uniqueName,
						    start=1,
					    	count=#curNode.processedFrames,
						    time =speed,        -- Optional. In ms.  If not supplied, then sprite is frame-based.
						    loopCount = loop}    -- Optional. Default is 0 (loop indefinitely)
						
				startAtLaunch = curNode.startAtLaunch;
				--seqName = curNode.uniqueName;
				--startFrame = 1+ #curNode.framesInfo;	
				
				--local coronaSprite = display.newMultiSprite(sequenceData )
				
				local coronaSprite = display.newSprite(imageSheet, sequenceDataTest )
				
				if(startAtLaunch)then
					coronaSprite:play()
				end
				return coronaSprite;
			end	
		end		
	end
	
	if(animationsListOnSprite ~= nil)then
		
		startFrame = 1;	
		local startAtLaunch = true;
		local multiSetArray = {};	for i = 1, #animationNodes do
			local curNode = animationNodes[i];
	
			local loop = 0;
			if false == curNode.loop then
				loop = curNode.repetitions
			end

			local speed = curNode.speed;
			if(speed < 0.001)then
				speed = 0.001
			end
			
			speed = speed*(#curNode.framesInfo)*1000;


			if(nil ~= animationsListOnSprite[curNode.uniqueName] or spr_animName == curNode.uniqueName)then
			
				
				local newsheet = sprite.newSpriteSheetFromData(	curNode.image,
	 															system.ResourceDirectory,
	 															curNode.oldApiSheetData )	 														 

				multiSetArray[#multiSetArray+1] = {	sheet = newsheet, 
												  	frames = curNode.processedFrames,
													lhSeqName = curNode.uniqueName,  
													lhStartFrm = startFrame, 
													lhFrmCount = #curNode.framesInfo, 
													lhTime = speed, 
													lhRepetitions = loop };	

				animationsSheet[#animationsSheet +1] = newsheet;
			
				startAtLaunch = curNode.startAtLaunch;
				seqName = curNode.uniqueName;
				startFrame = startFrame + #curNode.framesInfo;	
			end
		end
		
		
		if(#multiSetArray > 1)then
			spriteMultiSet = sprite.newSpriteMultiSet(multiSetArray)
		else
			spriteMultiSet = sprite.newSpriteSet(multiSetArray[1].sheet, 
												 multiSetArray[1].lhStartFrm, 
												 multiSetArray[1].lhFrmCount);
		end


		for i=1, #multiSetArray do
			local info = multiSetArray[i];
						
			sprite.add(spriteMultiSet, info.lhSeqName, 
									   info.lhStartFrm,
									   info.lhFrmCount,
									   info.lhTime,
									   info.lhRepetitions);
		end

		coronaSprite = sprite.newSprite( spriteMultiSet )
		
		coronaSprite:prepare(spr_animName)
	
		coronaSprite.currentFrame = coronaSprite.currentFrame+1;
		coronaSprite.currentFrame = coronaSprite.currentFrame-1;
	
		if(startAtLaunch)then
			coronaSprite:play()
		end
		
		return coronaSprite;
		
	end
	
	--else------------------------------------------------------------------------	   
		local options = 
		{ 
			frames = 
			{
				{ 
					x = spr_uvRect.origin.x,
					y = spr_uvRect.origin.y,
					width = spr_uvRect.size.width,
					height = spr_uvRect.size.height
				},
			},
			
		    sheetContentWidth = batch.width,
    		sheetContentHeight = batch.height
		}
		
		local imageSheet = graphics.newImageSheet( imageFile, options )
		
		animationsSheet[#animationsSheet +1] = imageSheet;
		
		local coronaSprite = display.newImage( imageSheet, 1)
	
		return coronaSprite;
end
--------------------------------------------------------------------------------
function lhAnimatioNodeGetFramesTableFromDictionary(properties)

	local framesInfo = {}
	local currentFrame = {}
	local info = properties["Frames"]
	
	for i = 1, #info do
		local currentFrameInfo = info[i]
		
		currentFrame = {name = currentFrameInfo["SpriteName"], 
					    rect = currentFrameInfo["FrameRect"]}
					 
		framesInfo[#framesInfo+1] = currentFrame;
		
		currentFrame = nil
		currentFrame = {}
	end
	
	return framesInfo;
end
	--------------------------------------------------------------------------------